package com.sykj.seaflow.sys.modual.dept.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sykj.seaflow.common.base.bean.PageQuery;
import com.sykj.seaflow.common.base.exception.CommonException;
import com.sykj.seaflow.sys.modual.dept.entity.SysDept;
import com.sykj.seaflow.sys.modual.dept.mapper.SysDeptMapper;
import com.sykj.seaflow.sys.modual.dept.params.*;
import com.sykj.seaflow.sys.modual.dept.service.SysDeptService;
import com.sykj.seaflow.sys.modual.user.entity.SysUser;
import com.sykj.seaflow.sys.modual.user.service.SysUserService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
@AllArgsConstructor
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {

    private final SysUserService sysUserService;

    @Override
    public void add(SysDeptAddParam sysDeptAddParam) {
        SysDept sysDept = BeanUtil.copyProperties(sysDeptAddParam, SysDept.class);
        this.save(sysDept);
    }

    @Override
    public void edit(SysDeptEditParam sysDeptEditParam) {
        SysDept sysDept = BeanUtil.copyProperties(sysDeptEditParam, SysDept.class);
        this.updateById(sysDept);
    }

    @Override
    public IPage<SysDept> page(SysDeptPageParam sysDeptPageParam, PageQuery<SysDept> pageQuery) {
        QueryWrapper<SysDept> query = buildQueryWrapper(sysDeptPageParam);
        return this.getBaseMapper().selectPage(pageQuery.getPage(), query);
    }

    private QueryWrapper<SysDept> buildQueryWrapper(SysDeptPageParam sysDeptPageParam) {
        QueryWrapper<SysDept> query = Wrappers.query();
        query.lambda().eq(ObjectUtil.isNotEmpty(sysDeptPageParam.getName()), SysDept::getName, sysDeptPageParam.getName());
        return query;
    }


    @Override
    public SysDept detail(SysDeptIdParam sysDeptIdParam) {
        return this.getById(sysDeptIdParam.getId());
    }

    @Transactional
    @Override
    public void deletes(List<SysDeptIdParam> ids) {
        List<Long> list = CollStreamUtil.toList(ids, SysDeptIdParam::getId);
        if(ObjectUtil.isNotEmpty(list)) {
            if(list.contains(1L)){
                throw new CommonException("顶级部门不能删除");
            }
            this.removeBatchByIds(list);
        }
    }

    @Override
    public void delete(SysDeptIdParam sysMenuIdParam) {
        this.removeById(sysMenuIdParam.getId());
    }

    @Override
    public List<Tree<String>> tree(SysDeptPageParam sysMenuPageParam) {
        List<SysDept> list = this.list();
        // 查询用户名
        List<Long> userIds = list.stream().map(SysDept::getDirector).distinct().filter(ObjectUtil::isNotNull).collect(Collectors.toList());
        List<SysUser> sysUsers = ObjectUtil.isEmpty(userIds) ? new ArrayList<>() : sysUserService.listByIds(userIds);
        Map<Long, SysUser> userMap = CollStreamUtil.toMap(sysUsers, SysUser::getId, Function.identity());

        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名 都有默认值的
        treeNodeConfig.setWeightKey("sortNum");
        List<Tree<String>> treeNodes = TreeUtil.<SysDept, String>build(list, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(String.valueOf(treeNode.getId()));
                    tree.setParentId(String.valueOf(treeNode.getPid()));
                    tree.setWeight(treeNode.getSortNum());
                    tree.setName(treeNode.getName());
                    tree.putExtra("levelCode", treeNode.getLevelCode());
                    tree.putExtra("director", treeNode.getDirector());
                    if(ObjectUtil.isNotNull(treeNode.getDirector())){
                        SysUser sysUser = userMap.get(treeNode.getDirector());
                        if(ObjectUtil.isNotNull(sysUser)){
                            tree.putExtra("directorName", sysUser.getNick());
                        }
                    }

                });
        return treeNodes;
    }

    @Override
    public List<SysDept> list(SysDeptQueryParam sysMenuQueryParam) {
        List<SysDept> list = this.list();
        return list;
    }
}
